package com.demo.sender.notice.dingtalk;

import com.alibaba.fastjson2.JSON;
import com.demo.common.ResultData;
import com.demo.request.NoticeBaseReq;
import com.demo.sender.notice.NoticeSenderService;
import com.demo.sender.notice.dingtalk.enums.DingTalkTypeEnum;
import com.demo.sender.notice.dingtalk.request.*;
import com.demo.sender.notice.dingtalk.response.DingTalkResult;
import com.demo.sender.notice.dingtalk.util.DingTalkSignUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 * 文档地址：<a href="https://open.dingtalk.com/document/orgapp/custom-robots-send-group-messages?spm=ding_open_doc.document.0.0.736e7f7fxW5hQS">https://open.dingtalk.com/document/orgapp/custom-robots-send-group-messages?spm=ding_open_doc.document.0.0.736e7f7fxW5hQS</a>
 *
 * @author wangfengchen
 */
@Slf4j
@Component
public class DingTalkSender implements NoticeSenderService {

  @Autowired
  private RestTemplate restTemplate;


  @Override
  public ResultData<Object> send(NoticeBaseReq req) {
    DingTalkTypeEnum typeEnum = DingTalkTypeEnum.match(req.getMsgType());
    if (ObjectUtils.isEmpty(typeEnum)) {
      return ResultData.fail("消息类型错误");
    }
    String sign = null;
    int timestamp = 0;
    if (StringUtils.isNotBlank(req.getSecret())) {
      String secret = req.getSecret();
      timestamp = (int) System.currentTimeMillis();
      sign = DingTalkSignUtil.genSign(secret, timestamp);
    }
    // 判断发送消息类型
    switch (typeEnum) {
      case TEXT:
        DingTalkTextReq dingTalkTextReq = JSON.parseObject(req.getContent(), DingTalkTextReq.class);
        dingTalkTextReq.setMsgtype(req.getMsgType());
        return send(req.getWebhook(), timestamp, sign, dingTalkTextReq);
      case LINK:
        DingTalkLinkReq dingTalkLinkReq = JSON.parseObject(req.getContent(), DingTalkLinkReq.class);
        dingTalkLinkReq.setMsgtype(req.getMsgType());
        return send(req.getWebhook(), timestamp, sign, dingTalkLinkReq);
      case MARKDOWN:
        DingTalkMarkdownReq dingTalkMarkdownReq = JSON.parseObject(req.getContent(), DingTalkMarkdownReq.class);
        dingTalkMarkdownReq.setMsgtype(req.getMsgType());
        return send(req.getWebhook(), timestamp, sign, dingTalkMarkdownReq);
      case ACTIONCARD:
        DingTalkActionCardReq dingTalkActionCardReq = JSON.parseObject(req.getContent(), DingTalkActionCardReq.class);
        dingTalkActionCardReq.setMsgtype(req.getMsgType());
        return send(req.getWebhook(), timestamp, sign, dingTalkActionCardReq);
      case FEEDCARD:
        DingTalkFeedCardReq dingTalkFeedCardReq = JSON.parseObject(req.getContent(), DingTalkFeedCardReq.class);
        dingTalkFeedCardReq.setMsgtype(req.getMsgType());
        return send(req.getWebhook(), timestamp, sign, dingTalkFeedCardReq);
      default:
        break;
    }
    return ResultData.success();
  }

  /**
   * 消息发送
   *
   * @param webhook
   * @param req
   * @return
   */
  private ResultData<Object> send(String webhook, int timestamp, String sign, DingTalkBaseReq req) {
    String botUrl = "https://oapi.dingtalk.com/robot/send?access_token=%s&timestamp=%s&sign=%s";
    String url = String.format(botUrl, webhook, timestamp, sign);
    log.info("钉钉消息发送，url = {}，request = {}", url, JSON.toJSONString(req));
    ResponseEntity<DingTalkResult> respEntity = this.restTemplate.postForEntity(url, req, DingTalkResult.class);
    log.info("钉钉消息发送，respEntity = {}", JSON.toJSONString(respEntity));
    if (ObjectUtils.isEmpty(respEntity)) {
      log.warn("钉钉消息发送失败");
      return ResultData.fail(501, "钉钉消息发送异常,直接返回");
    }
    if (respEntity.getStatusCode().value() != HttpStatus.OK.value() || respEntity.getBody() == null) {
      return ResultData.fail(respEntity.getStatusCodeValue(), respEntity.toString());
    }
    DingTalkResult result = respEntity.getBody();
    log.info("result = {} ", result);
    int code = result.getErrcode();
    if (code != 0) {
      String message = result.getErrmsg();
      log.error("钉钉消息发送失败, result = {} ", result);
      return ResultData.fail(code, message);
    } else {
      return ResultData.success();
    }
  }


}
